//
//  AppDelegate.m
//  Speedater
//
//  Created by NgoThang on 12/28/11.
//  Copyright (c) 2011 __MyCompanyName__. All rights reserved.
//

#import "AppDelegate.h"
#import "Home.h"
#import "Radar.h"
#import "Contact.h"
#import "Mail.h"
#import "AppCLLocation.h"
#import "JSON.h"

#define ItemKey @"ITEMKEY1"
#define TitleKey @"TITLEKEY1"

@implementation AppDelegate

@synthesize window = _window;
@synthesize tabBarController;
@synthesize appCLL;
@synthesize lat, lon;

- (void)dealloc
{
    [tabBarController release];
    [appCLL release];
    [_window release];
    [super dealloc]; 
}

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    /*
     * SETTINGS
     * Set the application defaults
     * tt-tech.${PRODUCT_NAME:rfc1034identifier}
     */    
    NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
    NSDictionary *appDefaults = [NSDictionary dictionaryWithObjectsAndKeys:
                                 @"https://date-server.speedater-app.com/", @"url_preference",
                                 @"YES", @"acoustic_signal",
                                 @"YES", @"vibration_alarm",
                                 @"YES", @"automatic_gps_query",
                                 @"5", @"interval_for_automatic_GPS_query", 
                                 @"4500", @"radius", 
                                 [[NSUserDefaults standardUserDefaults] stringForKey:@"username"], @"username",
                                 [[NSUserDefaults standardUserDefaults] stringForKey:@"password"], @"password",
                                 [[NSUserDefaults standardUserDefaults] stringForKey:@"mail_username"], @"mail_username",
                                 [[NSUserDefaults standardUserDefaults] stringForKey:@"mail_subject"], @"mail_subject",
                                 [[NSUserDefaults standardUserDefaults] stringForKey:@"mail_detail_id"], @"mail_detail_id",
                                 [[NSUserDefaults standardUserDefaults] stringForKey:@"contact_friend"], @"contact_friend",
                                 [[NSUserDefaults standardUserDefaults] stringForKey:@"gps_lat"], @"gps_lat",
                                 [[NSUserDefaults standardUserDefaults] stringForKey:@"gps_lon"], @"gps_lon",
                                 [[NSUserDefaults standardUserDefaults] stringForKey:@"tab_selected"], @"tab_selected",
                                 [[NSUserDefaults standardUserDefaults] stringForKey:@"tab_one"], @"tab_one",
                                 [[NSUserDefaults standardUserDefaults] stringForKey:@"tab_two"], @"tab_two",
                                 [[NSUserDefaults standardUserDefaults] stringForKey:@"tab_three"], @"tab_three",
                                 [[NSUserDefaults standardUserDefaults] stringForKey:@"tab_isBack"], @"tab_isBack",
                                 @"NO", @"auto_login",
                                 @"0", @"new_mail",
                                 [[NSUserDefaults standardUserDefaults] stringForKey:@"last_state"], @"last_state",nil];
    [defaults registerDefaults:appDefaults];
    [defaults synchronize];
    
    
    /*
     * local notification
     */
    [[UIApplication sharedApplication] registerForRemoteNotificationTypes:
        UIRemoteNotificationTypeBadge |
        UIRemoteNotificationTypeAlert |
        UIRemoteNotificationTypeSound];
    application.applicationIconBadgeNumber = 0;
    [self updateNotify];
    
    /*
     * GPS
     */
    self.appCLL = [[[AppCLLocation alloc] init] autorelease];
    
    /*
     * VIEW CONTROLLERS
     */
    self.tabBarController = [[[UITabBarController alloc] init] autorelease];
    
    Home *home = [[Home alloc] init];
    UINavigationController *navController1 = [[UINavigationController alloc] initWithRootViewController:home];
    
    Radar *radar = [[Radar alloc] init];
    UINavigationController *navController2 = [[UINavigationController alloc] initWithRootViewController:radar];
    
    Contact *contact = [[Contact alloc] init];
    UINavigationController *navController3 = [[UINavigationController alloc] initWithRootViewController:contact];
    
    Mail *mail = [[Mail alloc] init];
    UINavigationController *navController4 = [[UINavigationController alloc] initWithRootViewController:mail];
    
    NSArray *controllers = [NSArray arrayWithObjects:navController1, navController2, navController3, navController4, nil];
    tabBarController.viewControllers = controllers;
    
    [home release];
    [radar release];
    [contact release];
    [mail release];
    [navController1 release];
    [navController2 release];
    [navController3 release];
    [navController4 release];
    
    self.tabBarController.tabBar.hidden = YES;
    
    UIView *view = [self.tabBarController.view.subviews objectAtIndex:0];
    [view setFrame:CGRectMake(view.frame.origin.x, view.frame.origin.y, view.frame.size.width, 480)];
    
    self.window = [[[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]] autorelease];
    [self.window addSubview:tabBarController.view];
    [self.window makeKeyAndVisible];
    return YES;
}

- (void)applicationWillResignActive:(UIApplication *)application
{
    /*
     Sent when the application is about to move from active to inactive state. This can occur for certain types of temporary interruptions (such as an incoming phone call or SMS message) or when the user quits the application and it begins the transition to the background state.
     Use this method to pause ongoing tasks, disable timers, and throttle down OpenGL ES frame rates. Games should use this method to pause the game.
     */
    //NSLog(@"APP -> applicationWillResignActive");
    
    hasIn = NO;
    
    [self updateNotify];
}

- (void)applicationDidEnterBackground:(UIApplication *)application
{
    /*
     Use this method to release shared resources, save user data, invalidate timers, and store enough application state information to restore your application to its current state in case it is terminated later. 
     If your application supports background execution, this method is called instead of applicationWillTerminate: when the user quits.
     */
    //NSLog(@"APP -> applicationDidEnterBackground");
    
    if (bgTask != UIBackgroundTaskInvalid) {
        dispatch_async(dispatch_get_main_queue(), ^{
            [application endBackgroundTask:bgTask];
            bgTask = UIBackgroundTaskInvalid;
        });
    }
    
    bgTask = [application beginBackgroundTaskWithExpirationHandler: ^{
        dispatch_async(dispatch_get_main_queue(), ^{
            [application endBackgroundTask:bgTask];
            bgTask = UIBackgroundTaskInvalid;
        });
	}];
    
    //    bgTask = [application beginBackgroundTaskWithExpirationHandler: ^{
    //        [application endBackgroundTask:self->bgTask];
    //        self->bgTask = UIBackgroundTaskInvalid;
    //	}];
}

- (void)applicationWillEnterForeground:(UIApplication *)application
{
    /*
     Called as part of the transition from the background to the inactive state; here you can undo many of the changes made on entering the background.
     */
    //NSLog(@"APP -> applicationWillEnterForeground");
    application.applicationIconBadgeNumber = 0;
}

- (void)applicationDidBecomeActive:(UIApplication *)application
{
    /*
     Restart any tasks that were paused (or not yet started) while the application was inactive. If the application was previously in the background, optionally refresh the user interface.
     */
    //NSLog(@"APP -> applicationDidBecomeActive");
    
    hasIn = YES;
    
    [self updateNotify];
}

- (void)applicationWillTerminate:(UIApplication *)application
{
    /*
     Called when the application is about to terminate.
     Save data if appropriate.
     See also applicationDidEnterBackground:.
     */
    //NSLog(@"APP -> applicationWillTerminate");
}

- (void)application:(UIApplication *)application didReceiveLocalNotification:(UILocalNotification *)notif  
{
    //NSLog(@"APP -> didReceiveLocalNotification");
    
    application.applicationIconBadgeNumber = 0;
    
    // remove message
    if (notifyMessage) 
    {
        [notifyMessage dismissWithClickedButtonIndex:0 animated:YES];
        [notifyMessage removeFromSuperview];
        [notifyMessage release];
        notifyMessage = nil;
    }
    
    if (!hasIn) {
        [[[[tabBarController.viewControllers objectAtIndex:2] topViewController] navigationController] popToRootViewControllerAnimated:NO];
        
        Contact *ct = (Contact *)[[[tabBarController.viewControllers objectAtIndex:2] viewControllers] objectAtIndex:0];
        
        [ct findContactButtonClick:NULL];
        
        tabBarController.selectedIndex = 2;
    }
    else {
        NSString *msgItem = [notif.userInfo objectForKey:ItemKey];
        NSString *msgTitle = [notif.userInfo objectForKey:TitleKey];
        
        notifyMessage = [[UIAlertView alloc]
                         initWithTitle:msgTitle 
                         message:msgItem 
                         delegate:self 
                         cancelButtonTitle:NSLocalizedString(@"Cancel", nil) 
                         otherButtonTitles:NSLocalizedString(@"Ok", nil), nil];
        [notifyMessage show];
        
        if ([[NSUserDefaults standardUserDefaults] boolForKey:@"vibration_alarm"]) {
            [self playAlarm];
        }
    }
}

- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
{
    // Ok button click
    if (buttonIndex) {
        [[[[tabBarController.viewControllers objectAtIndex:2] topViewController] navigationController] popToRootViewControllerAnimated:NO];
        
        Contact *ct = (Contact *)[[[tabBarController.viewControllers objectAtIndex:2] viewControllers] objectAtIndex:0];
        
        [ct findContactButtonClick:NULL];
        
        tabBarController.selectedIndex = 2;
    }
}

# pragma -
# pragma - custom functions

- (void)updateNotify
{
    int intervalTime = [[[NSUserDefaults standardUserDefaults] stringForKey:@"interval_for_automatic_GPS_query"] intValue];
    
    if (intervalTime == 0) intervalTime = 10;
    
    intervalTime *= 60;
    
    //NSLog(@"intervalTime %d: ", intervalTime);
    
    if ([notify timeInterval] != intervalTime) {
        if (notify) {
            [notify invalidate];
            notify = nil;
        }
        notify = [NSTimer scheduledTimerWithTimeInterval:intervalTime target:self selector:@selector(updateGPS) userInfo:nil repeats:YES];
    }
}

- (void)updateGPS 
{
    if (![[NSUserDefaults standardUserDefaults] boolForKey:@"automatic_gps_query"]) return;
    if (![[[NSUserDefaults standardUserDefaults] stringForKey:@"username"] length]) return;
    
    //NSLog(@"update GPS (%f, %f)", self.lat, self.lon);
    
    NSString *postString = [NSString stringWithFormat:@"op=findfriend&username=%@&radius=%d&lat=%f&lon=%f",
                            [[NSUserDefaults standardUserDefaults] stringForKey:@"username"],
                            [[[NSUserDefaults standardUserDefaults] stringForKey:@"radius"] intValue], 
                            self.lat, 
                            self.lon];
    
    NSData *postData = [postString dataUsingEncoding:NSUTF8StringEncoding];
    NSString *postLength = [NSString stringWithFormat:@"%d", [postString length]];
    NSMutableURLRequest *request = [NSMutableURLRequest requestWithURL: [NSURL URLWithString:[[NSUserDefaults standardUserDefaults] stringForKey:@"url_preference"]]];
    [request setHTTPMethod:@"POST"];
    [request setValue:@"application/json" forHTTPHeaderField:@"Accept"];
    [request setValue:@"application/x-www-form-urlencoded" forHTTPHeaderField:@"Content-Type"];
    [request setValue:postLength forHTTPHeaderField:@"Content-Length"];
    [request setHTTPBody:postData]; 
    NSURLConnection *conn = [[NSURLConnection alloc] initWithRequest:request delegate:self];
    if (conn) {
        // init data 
        responseData = [[NSMutableData data ] retain];
    }
    [conn release];
}

- (void) playAlarm
{
    SystemSoundID audioID;
    NSString *volleyPath = [[NSBundle mainBundle] pathForResource:@"alarmsound" ofType:@"caf"];
	CFURLRef volleyURL = (CFURLRef ) [NSURL fileURLWithPath:volleyPath];
	AudioServicesCreateSystemSoundID (volleyURL, &audioID);
    AudioServicesPlaySystemSound(audioID);
}

- (void) playCat 
{
    SystemSoundID audioID;
    NSString *volleyPath = [[NSBundle mainBundle] pathForResource:@"cat" ofType:@"caf"];
	CFURLRef volleyURL = (CFURLRef ) [NSURL fileURLWithPath:volleyPath];
	AudioServicesCreateSystemSoundID (volleyURL, &audioID);
    AudioServicesPlaySystemSound(audioID);
}

- (void) playTiger 
{
    SystemSoundID audioID;
    NSString *volleyPath = [[NSBundle mainBundle] pathForResource:@"tiger" ofType:@"caf"];
	CFURLRef volleyURL = (CFURLRef ) [NSURL fileURLWithPath:volleyPath];
	AudioServicesCreateSystemSoundID (volleyURL, &audioID);
    AudioServicesPlaySystemSound(audioID);
}

#pragma mark -
#pragma mark NSURLConnectionDelegete

- (void)connection:(NSURLConnection *)connection didReceiveResponse:(NSURLResponse *)response 
{
	[responseData setLength:0];
}

- (void)connection:(NSURLConnection *)connection didReceiveData:(NSData *)data 
{
	[responseData appendData:data];
}

- (void)connection:(NSURLConnection *)connection didFailWithError:(NSError *)error 
{
    [responseData release];
    responseData = nil;	
}

- (void)connectionDidFinishLoading:(NSURLConnection *)connection 
{
	NSString *responseString = [[NSString alloc] initWithData:responseData encoding:NSUTF8StringEncoding];
    
    //NSLog(@"%@", [responseString JSONValue]);
    
    NSMutableArray *results = [(NSMutableDictionary *)[responseString JSONValue] objectForKey:@"friendlist"];
    NSInteger count = [results count] - 1;
    
    if (count>0) {
        [[UIApplication sharedApplication] cancelAllLocalNotifications];
        
        UILocalNotification *localNotif = [[UILocalNotification alloc] init];
        if (localNotif) {
            localNotif.alertBody = [NSString stringWithFormat:NSLocalizedString(@"Speedater has %d possible dates for you!.\nNow open the app to take a look at the suggestions!", nil), count];
            localNotif.alertAction = NSLocalizedString(@"Speedater", nil);
            if ([[NSUserDefaults standardUserDefaults] boolForKey:@"vibration_alarm"])
                localNotif.soundName = @"alarmsound.caf";
            localNotif.applicationIconBadgeNumber = 1;
            NSDictionary *infoDict = [NSDictionary dictionaryWithObjectsAndKeys:
                                      [NSString stringWithFormat:NSLocalizedString(@"Speedater has %d possible dates for you!", nil), count], ItemKey,
                                      @"Speedater", TitleKey, nil];
            localNotif.userInfo = infoDict;
            
            [[UIApplication sharedApplication] presentLocalNotificationNow:localNotif];
            
            [localNotif release];
        }
    }
    
    
    [responseString release];
    
    [responseData release];
    responseData = nil;
}

#pragma -
#pragma - static functions

+ (void)updateTabBarItem:(UITabBar *)tabBar withMailValue:(NSInteger)mailValue andUpdateMute:(BOOL)isUpdateMute
{
    if (isUpdateMute)
        [[NSUserDefaults standardUserDefaults] setBool:![[NSUserDefaults standardUserDefaults] boolForKey:@"automatic_gps_query"] forKey:@"automatic_gps_query"];
    [[tabBar.items objectAtIndex:3] setImage:[UIImage imageNamed:[NSString stringWithFormat:@"ico_mute_%d.png", [[NSUserDefaults standardUserDefaults] boolForKey:@"automatic_gps_query"]]]];
    
    if (mailValue >= 0)
        [[NSUserDefaults standardUserDefaults] setInteger:mailValue forKey:@"new_mail"];
    
    if ([[NSUserDefaults standardUserDefaults] integerForKey:@"new_mail"])
        [[tabBar.items objectAtIndex:2] setBadgeValue:[[NSUserDefaults standardUserDefaults] stringForKey:@"new_mail"]];
    else
        [[tabBar.items objectAtIndex:2] setBadgeValue:nil];
}

+ (void)saveState:(NSInteger)tabBarIndex withViewController:(UIViewController *)currentViewController
{
    NSString *last_state = [NSString stringWithFormat:@"%d", tabBarIndex];
    for (UIViewController *vc in currentViewController.navigationController.viewControllers) {
        last_state = [last_state stringByAppendingFormat:@"$%@",[vc classForCoder]];
    }
    //NSLog(@"%@", last_state);
    [[NSUserDefaults standardUserDefaults] setValue:last_state forKey:@"last_state"];   
    
    // back history
    if (![[NSUserDefaults standardUserDefaults] boolForKey:@"tab_isBack"]) {
        NSInteger idx = [[NSUserDefaults standardUserDefaults] integerForKey:@"tab_selected"];
        switch (tabBarIndex) {
            case 1:
                [[NSUserDefaults standardUserDefaults] setInteger:idx forKey:@"tab_one"];
                break;
            case 2:
                [[NSUserDefaults standardUserDefaults] setInteger:idx forKey:@"tab_two"];
                break;
            case 3:
                [[NSUserDefaults standardUserDefaults] setInteger:idx forKey:@"tab_three"];
                break;
            default:
                break;
        }
    }
    [[NSUserDefaults standardUserDefaults] setInteger:tabBarIndex forKey:@"tab_selected"];
    [[NSUserDefaults standardUserDefaults] setBool:NO forKey:@"tab_isBack"];
    [[NSUserDefaults standardUserDefaults] synchronize];
}

+ (NSString *)encodeText:(NSString *)string 
{
    NSString * str = [string stringByReplacingOccurrencesOfString:@"&" withString:@"#38#"];
    str = [str stringByReplacingOccurrencesOfString:@";" withString:@"#52#"];
    return str;
}

+ (NSString *)decodeText:(NSString *)string
{
    NSString * str = [string stringByReplacingOccurrencesOfString:@"#38#" withString:@"&"];
    str = [str stringByReplacingOccurrencesOfString:@"#52#" withString:@";"];
    return str;
}

@end
